winsafe\kernel\handles/
handle_traits.rs

1#![allow(non_snake_case)]
2
3use std::{fmt, hash};
4
5/// A native
6/// [handle](https://learn.microsoft.com/en-us/windows/win32/sysinfo/handles-and-objects),
7/// implemented by all handle types.
8///
9/// Prefer importing this trait through the prelude:
10///
11/// ```no_run
12/// use winsafe::prelude::*;
13/// ```
14pub trait Handle:
15	Sized
16	+ PartialEq
17	+ Eq
18	+ Send
19	+ hash::Hash
20	+ fmt::Debug
21	+ fmt::Display
22	+ fmt::LowerHex
23	+ fmt::UpperHex
24{
25	/// The null, uninitialized handle; equals to `0`.
26	const NULL: Self;
27
28	/// The invalid handle; equals to `-1`.
29	///
30	/// Operations upon this handle will fail with
31	/// [`ERROR::INVALID_HANDLE`](crate::co::ERROR::INVALID_HANDLE) error code.
32	const INVALID: Self;
33
34	/// Creates a new handle object by wrapping a pointer.
35	///
36	/// This method can be used as an escape hatch to interoperate with other
37	/// libraries.
38	///
39	/// # Safety
40	///
41	/// Be sure the pointer has the correct type and isn't owned by anyone else,
42	/// otherwise you may cause memory access violations.
43	#[must_use]
44	unsafe fn from_ptr(p: *mut std::ffi::c_void) -> Self;
45
46	/// Returns a raw copy of the underlying handle pointer.
47	///
48	/// # Safety
49	///
50	/// As the name implies, `raw_copy` returns a raw copy of the handle, so
51	/// closing one of the copies won't close the others. This means a handle
52	/// can be used after it has been closed, what can lead to errors and
53	/// undefined behavior. Even worse: sometimes Windows reuses handle values,
54	/// so you can call a method on a completely different handle type, what can
55	/// be catastrophic.
56	///
57	/// However, in some cases the Windows API *demands* a copy of the handle –
58	/// `raw_copy` is an escape hatch to fill this gap.
59	#[must_use]
60	unsafe fn raw_copy(&self) -> Self {
61		Self::from_ptr(self.ptr())
62	}
63
64	/// Returns a mutable reference to the underlying raw pointer.
65	///
66	/// This method can be used as an escape hatch to interoperate with other
67	/// libraries.
68	///
69	/// # Safety
70	///
71	/// This method exposes the raw pointer used by raw Windows calls. It's an
72	/// opaque pointer to an internal Windows structure, and no dereferencings
73	/// should be attempted.
74	#[must_use]
75	unsafe fn as_mut(&mut self) -> &mut *mut std::ffi::c_void;
76
77	/// Returns the underlying raw pointer.
78	///
79	/// This method exposes the raw pointer used by raw Windows calls. It's an
80	/// opaque pointer to an internal Windows structure, and no dereferencings
81	/// should be attempted.
82	///
83	/// This method can be used as an escape hatch to interoperate with other
84	/// libraries.
85	#[must_use]
86	fn ptr(&self) -> *mut std::ffi::c_void;
87
88	/// Returns `None` if the handle is null or invalid, otherwise returns
89	/// `Some(&self)`.
90	///
91	/// # Examples
92	///
93	/// ```no_run
94	/// use winsafe::{self as w, prelude::*};
95	///
96	/// let hfile = w::HFILE::NULL;
97	///
98	/// match hfile.as_opt() {
99	///     Some(hfile) => println!("Never prints"),
100	///     None => println!("The handle is null"),
101	/// }
102	/// ```
103	#[must_use]
104	fn as_opt(&self) -> Option<&Self> {
105		if *self == Self::NULL || *self == Self::INVALID {
106			None
107		} else {
108			Some(self)
109		}
110	}
111}